import { useRequest } from 'ahooks';
import {
  forwardRef,
  PropsWithChildren,
  useEffect,
  useImperativeHandle,
  useState,
} from 'react';
import CommonTable, { type CommonTableProps } from '../CommonTable';
import QueryForm, { type QueryFormProps } from '../QueryForm';
import CrudFormLayout from './CurdFormLayout';
import styles from './index.less';

interface CrudProps extends PropsWithChildren {
  fields: QueryFormProps['fields'];
  columns: CommonTableProps['columns'];
  request: (params: any) => Promise<{
    data: any[];
    total: number;
  }>;
  queryFormProps?: QueryFormProps;
  transformParams?: (params: any) => any;
  rowKey?: string;
  toolbar?: React.ReactNode;
  tableProps?: CommonTableProps;
  onParamsChange?: (params: any) => void;
}
interface CrudRef {
  reload: () => Promise<any>;
  getParams: () => any;
}
const Crud = forwardRef((props: CrudProps, ref) => {
  const {
    request,
    columns,
    fields,
    queryFormProps,
    transformParams,
    rowKey,
    toolbar,
    tableProps,
    onParamsChange,
  } = props;
  const { data, runAsync, refreshAsync, loading } = useRequest(request, {
    manual: true,
  });
  const [params, setParams] = useState<{
    index: number;
    size: number;
    [key: string]: any;
  }>({
    index: 0,
    // @ts-ignore
    size: tableProps?.pagination?.defaultPageSize || 20,
    ...queryFormProps?.initialValues,
  });

  useEffect(() => {
    const resultParams = transformParams?.(params) || params;
    runAsync(resultParams);
    onParamsChange?.(resultParams);
  }, [params]);

  useImperativeHandle<any, CrudRef>(ref, () => ({
    reload: refreshAsync,
    getParams: () => transformParams?.(params) || params,
  }));

  const handleSearch = (values?: any) => {
    const { size } = params;
    setParams({
      ...values,
      size,
      index: 0,
    });
  };
  return (
    <div className={styles['crud']}>
      <header className={styles['crud-header']}>
        <QueryForm
          fields={fields}
          {...queryFormProps}
          onSearch={handleSearch}
        />
      </header>
      <div className={styles['crud-toolbar']}>{toolbar}</div>
      <section className={styles['crud-content']}>
        <CommonTable
          rowKey={rowKey}
          loading={loading}
          columns={columns}
          dataSource={data?.data || []}
          {...tableProps}
          pagination={
            typeof tableProps?.pagination === 'boolean'
              ? false
              : {
                  current: params.index + 1,
                  onChange: (page, pageSize) => {
                    setParams((prev) => ({
                      ...prev,
                      index: page - 1,
                      size: pageSize,
                    }));
                  },
                  pageSize: params.size,
                  total: data?.total || 0,
                  ...tableProps?.pagination,
                }
          }
        />
      </section>
    </div>
  );
});
export default Crud;
export { CrudFormLayout };
